# app.py
import os
import subprocess
from urllib.parse import unquote
from pathlib import Path
from flask import Flask, render_template, request, jsonify, send_from_directory

app = Flask(__name__)

BASE_DIR = Path(__file__).resolve().parent
RESOURCES_DIR = BASE_DIR / "resources"
RESOURCES_DIR.mkdir(exist_ok=True)


def git_run(args, cwd=None):
    return subprocess.run(
        args, cwd=cwd or BASE_DIR, capture_output=True, text=True, check=False
    )


def ensure_parent_dirs(path: Path):
    path.parent.mkdir(parents=True, exist_ok=True)


def normalize_relpath(relpath: str) -> str:
    p = Path(relpath.strip().lstrip("/")).as_posix()
    while p.startswith("../"):
        p = p[3:]
    return p


@app.route("/", methods=["GET"])
def index():
    items = []
    for root, dirs, files in os.walk(RESOURCES_DIR):
        root_path = Path(root)
        for d in dirs:
            rel = (root_path / d).relative_to(RESOURCES_DIR).as_posix()
            items.append(("dir", rel))
        for f in files:
            rel = (root_path / f).relative_to(RESOURCES_DIR).as_posix()
            items.append(("file", rel))
    items.sort(key=lambda x: (x[0], x[1]))
    return render_template("index.html", items=items)


@app.route("/upload", methods=["POST"])
def upload():
    files = request.files.getlist("files[]")
    paths = request.form.getlist("paths[]")
    roots = request.form.getlist("batch_roots[]")  # 去重后的顶层名称集合

    if not files or not paths or len(files) != len(paths):
        return jsonify({"ok": False, "error": "No files or mismatched paths"}), 400

    saved_paths = []
    for f, rel in zip(files, paths):
        safe_rel = normalize_relpath(rel)
        dest = RESOURCES_DIR / safe_rel
        ensure_parent_dirs(dest)
        f.save(dest)
        saved_paths.append(dest.as_posix())

    git_add = git_run(["git", "add", "resources"])
    if git_add.returncode != 0:
        return jsonify({"ok": False, "error": f"git add failed: {git_add.stderr}"}), 500

    commit_results = []
    for root in roots:
        msg = root.strip().strip('"').strip("'")
        if not msg:
            msg = "upload"
        commit = git_run(["git", "commit", "-m", msg])
        commit_results.append(
            {
                "root": root,
                "returncode": commit.returncode,
                "stdout": commit.stdout,
                "stderr": commit.stderr,
            }
        )

    # push
    # push = git_run(["git", "push"])
    # if push.returncode != 0:
    #     return (
    #         jsonify(
    #             {
    #                 "ok": False,
    #                 "error": f"git push failed: {push.stderr}",
    #                 "commit_results": commit_results,
    #             }
    #         ),
    #         500,
    #     )

    return jsonify(
        {
            "ok": True,
            "saved": saved_paths,
            "commit_results": commit_results,
            # "push_stdout": push.stdout,
        }
    )


@app.route("/delete", methods=["POST"])
def delete():
    data = request.get_json()
    relpath = data.get("path", "")
    relpath = unquote(relpath)
    safe_rel = normalize_relpath(relpath)
    target = RESOURCES_DIR / safe_rel
    if not target.exists():
        return jsonify({"ok": False, "error": "File or directory not found"}), 404
    try:
        if target.is_file():
            target.unlink()
        else:
            import shutil

            shutil.rmtree(target)
    except Exception as e:
        return jsonify({"ok": False, "error": str(e)}), 500

    git_rm = git_run(
        ["git", "rm", "-r", "--cached", target.relative_to(BASE_DIR).as_posix()]
    )
    git_add = git_run(["git", "add", "resources"])
    commit = git_run(["git", "commit", "-m", f"delete {safe_rel}"])
    push = git_run(["git", "push"])
    return jsonify(
        {
            "ok": True,
            "deleted": safe_rel,
            "git_rm": git_rm.stdout,
            "commit": commit.stdout,
            "push": push.stdout,
        }
    )


@app.route("/download", methods=["GET"])
def download():
    relpath = request.args.get("path", "")
    relpath = unquote(relpath)
    safe_rel = normalize_relpath(relpath)
    target = RESOURCES_DIR / safe_rel
    if not target.exists() or not target.is_file():
        return "File not found", 404
    return send_from_directory(RESOURCES_DIR, safe_rel, as_attachment=True)


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=80, debug=True)
